﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.SharepointSnifferPackage;


namespace ServerExplorer.SharePointConnections.SharepointSiteInfo.Entities
{

    public class ProcessFolderFiles
    {
        public static Object processFolder = new Object();
        public static Object processInfoUpdate = new Object();
        public static Object accessWebList = new Object();


        private static int CountProcessFolder = 0;
        private static int Added = 0;
        private static int Removed = 0;

        private ManualResetEvent _doneEvent;

        private string _webGuid;

        private List<Folder> _folders;
        private List<Page> _pages;

        private Object _outMessage;

        private ManualResetEvent _pageEvent;

        // Constructor.
        public ProcessFolderFiles(string webGuid, List<Folder> folders, List<Page> pages, ManualResetEvent doneEvent, Object outMessage)
        {
            _webGuid = webGuid;
            _doneEvent = doneEvent;
            _folders = new List<Folder>(folders);
            _pages = new List<Page>(pages);
            _outMessage = outMessage;
            _pageEvent = new ManualResetEvent(true);
            lock (processInfoUpdate)
            {
                MyControl mc = (MyControl)_outMessage;
                CountProcessFolder++;
                Added++;
                mc.TextT1(string.Format("Queue:{0} Processed:{1} Remaining:{2}", Added.ToString(), Removed.ToString(), CountProcessFolder.ToString()));
                _doneEvent.Reset();
            }
        }

        // Wrapper method for use with thread pool.
        public void ThreadPoolCallback(Object threadContext)
        {
            FillFolder();
            lock (processInfoUpdate)
            {
                MyControl mc = (MyControl)_outMessage;
                CountProcessFolder--;
                Removed++;
                mc.TextT1(string.Format("Queue:{0} Processed:{1} Remaining:{2}", Added.ToString(), Removed.ToString(), CountProcessFolder.ToString()));
                if (CountProcessFolder == 0)
                {
                    _doneEvent.Set();
                }
            }
        }

        private void GetWebPartInfo()
        {
            List<WebPartInfo> webPartsInfoLocal = new List<WebPartInfo>();
            foreach (Page p in _pages)
            {
                String[] wParameters = new String[] { _webGuid, p.RelativeUrl };
                lock (processFolder)
                {
                    p.WebParts.AddRange(Access.conn.ExecuteCommand<string[], List<WebPartInfo>>
                             (SharepointSiteInfoCommandsIDs.GetSharepointSitewebPartInfo, wParameters));
                }
                webPartsInfoLocal.AddRange(p.WebParts.Where(wh => wh.WebPartTitle != "(None)"));
            }
            lock (accessWebList)
            {
                Access.AllWebParts.AddRange(webPartsInfoLocal);
            }
            _pageEvent.Set();
        }

        private void FillFolder()
        {
            if (_pages.Count > 0)
            {
                _pageEvent.Reset();
                Thread pageThread = new Thread(GetWebPartInfo);
                pageThread.Start();
            }

            if (_folders.Count > 0)
            {
                do
                {
                    Folder firstFolderinList = _folders.FirstOrDefault();
                    String[] parameters = new String[] { _webGuid, firstFolderinList.Guid };

                    FolderFiles folderFiles = null;
                    lock (processFolder)
                    {
                        folderFiles = Access.conn.ExecuteCommand<String[], FolderFiles>
                                     (SharepointSiteInfoCommandsIDs.GetSharepointSitewebPartInfoFiles, parameters);
                    }
                    if (folderFiles != null)
                    {
                        if (folderFiles.Folders.Count > 0)
                        {
                            firstFolderinList.SubFolder.AddRange(folderFiles.Folders);
                        }

                        if (folderFiles.Pages.Count > 0)
                        {
                            firstFolderinList.Pages.AddRange(folderFiles.Pages);
                        }
                        ProcessFolderFiles processFolderFiles = new ProcessFolderFiles(_webGuid, firstFolderinList.SubFolder, firstFolderinList.Pages, _doneEvent, _outMessage);
                        ThreadPool.QueueUserWorkItem(processFolderFiles.ThreadPoolCallback);
                    }
                    _folders.Remove(firstFolderinList);
                }
                while (_folders.Count > 0);
            }
            _pageEvent.WaitOne();
        }
    }
}

